package aad.storyboard.model;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import aad.storyboard.controller.GUIComposer;
import android.util.Log;

public abstract class Animation implements Observer, Animatable, Cloneable{
	
	protected ArrayList<Image> images;
	protected int time, currentDuration, duration, intervals;
	protected AnimationState state;
	protected Animatable baseAnimation;
	protected boolean active = false;
	protected boolean started = false;
	protected boolean isDecorating = false;
	

	public Animation(int duration){
		state = AnimationStateStopped.getInstance();
		images = new ArrayList<Image>();
		time = -1;
		this.duration = duration;
		intervals = this.duration * GUIComposer.getInstance().getFps();;
		this.currentDuration = 0;
		this.baseAnimation = new PlainAnimatable();
		
	}
	
	public Animation(int duration, int t){
		state = AnimationStateStopped.getInstance();
		images = new ArrayList<Image>();
		time = t;
		this.duration = duration;
		this.currentDuration = 0;
		intervals = this.duration * GUIComposer.getInstance().getFps();;
		this.baseAnimation = new PlainAnimatable();
	}
	
	public Animation(Animation baseAnim){
		state = AnimationStateStopped.getInstance();
		baseAnimation = baseAnim;
		isDecorating = true;
		this.duration = baseAnim.duration;
		intervals = this.duration * GUIComposer.getInstance().getFps();;
		this.time = baseAnim.getTime();
		this.images = baseAnim.getImages();
		this.currentDuration = 0;
	}
	
	public int getTime() {
		return time;
	}

	public void setTime(int time) {
		this.time = time;
	}
	
	public void addImage(Image go){
		this.images.add(go);
	}
	
	public ArrayList<Image> getImages(){
		return this.images;
	}

	public void update(Observable frc, Object arg){
		if(this.currentDuration>this.intervals){
			this.stop();
			for (Image img:this.getImages())
			{
				img.clearBlurEffect();
			}
		}
		if(this.isActive()){
			if(this.isDecorating){
				this.baseAnimation.update(frc, arg);
			}
			this.animate();			
			this.currentDuration ++;
		}
	}
	
	public abstract void animate();
		
	public void undo(){
		this.started = false;
	}
	
	public abstract void adjustParameters();
	
	public void start() {
		Log.e("TAG","Animation started"+this.state);
		this.baseAnimation.start();
		this.state.start(this);
	}
	
	public void stop() {
		this.baseAnimation.stop();
		this.state.stop(this);
		
	}
	
	public void pause(){
		this.baseAnimation.pause();
		this.state.pause(this);
	}

	public boolean isActive() {
		return active;
	}
	
	public void setActive(boolean a){
		this.active = a;
	}

	public void setState(AnimationState state) {
		baseAnimation.setState(state);
		this.state = state;
	}

	public void resetCurrentDuration(){
		this.currentDuration = 0;
	}
	
	public Animation clone(){
		try {
			return (Animation) super.clone();
		} catch (CloneNotSupportedException e) {
			return null;
		}
	}

	public boolean isStarted() {
		return started;
	}

	public void setStarted(boolean started) {
		this.started = started;
	}
	public AnimationState getState(){
		return this.state;
	}
}
